Skip to content

S04-01 Web-DOM

[TOC]

DOM API

EventTarget

构造函数

  • EventTarget()(),创建一个新的 EventTarget 对象实例。

实例方法

Node

实例属性

  • Node.parentElementElement,只读,返回一个当前节点的父节点 Element 。如果当前节点没有父节点或者说父节点不是一个元素 (Element), 这个属性返回 null。
  • Node.parentNodeNode,只读,返回一个当前节点 Node的父节点。如果没有这样的节点返回 null。
  • Node.childNodesNodeList,只读,返回一个包含了该节点所有子节点的实时的NodeList。NodeList 是动态变化的。
  • Node.firstChildNode,只读,返回该节点的第一个子节点Node,如果该节点没有子节点则返回null。
  • Node.lastChildNode,只读,返回该节点的最后一个子节点Node,如果该节点没有子节点则返回null。
  • Node.previousSiblingNode,只读,返回一个当前节点同辈的前一个节点 ( Node) ,如果没有返回null。
  • Node.nextSiblingNode,只读,返回与该节点同级的下一个节点 Node,如果没有返回null。
  • Node.nodeNameDOMString,只读,返回一个包含该节点名字的DOMString。
  • Node.nodeTypenumber,只读,返回一个与该节点类型对应的无符号短整型的值。
  • Node.nodeValuestring,返回或设置当前节点的值。
  • Node.textContentstring,返回或设置一个元素内所有子节点及其后代的文本内容。
  • 其他Node.baseURINode.baseURIObjectNode.isConnectedNode.ownerDocumentNode.parentElement

实例方法

Document

继承:Node - EventTarget

构造函数:

  • Document()(),创建一个新的 Document 对象。

实例属性:

实例方法:

事件类型:

HTMLDocument

继承:Document - Node - EventTarget

实例属性:

实例方法:

XMLDocument

继承:Document - Node - EventTarget

没有额外的属性和方法

Element

继承:Node - EventTarget

实例属性:

实例方法:

  • Element.append()(...param),在元素的最后一个子元素后插入一组 Node 对象或字符串。
  • Element.prepend()(nodes),在元素的第一个子元素之前插入一组 Node 对象或字符串。
  • Element.before()(...param),在 Element 父节点的子节点列表中插入一组Node对象或字符串,位于 Element 之前。
  • Element.after()(...node),在 Element 父节点的子节点列表中插入一组 Node 对象或字符串,位于 Element 之后。
  • Element.insertAdjacentElement()(position, element),将指定元素节点插入调用该函数的元素的指定位置。
  • Element.insertAdjacentHTML()(position, text),解析 HTML 或 XML 文本,并将生成的节点插入树中指定的位置。
  • Element.insertAdjacentText()(where, data),将给定的文本节点插入调用该函数的元素的指定位置。
  • Element.remove()(),从父元素的子元素列表中删除该元素。
  • Element.replaceChildren()(...param),用一组指定的新子节点替换 Node 的现有子节点。
  • Element.replaceWith()(...param),用一组 Node 对象或字符串替换父元素子元素列表中的元素。
  • 获取元素:
  • Element.querySelector()(selectors),返回相对于元素符合指定选择器字符串的第一个 Node。
  • Element.querySelectorAll()(selectors),返回 NodeList 中相对于元素符合指定选择器字符串的节点。
  • Element.getElementsByClassName()(names),返回一个实时的 HTMLCollection,其中包含当前元素的所有后代,这些后代拥有参数中给定的类列表。
  • Element.getElementsByTagName()(tagName),返回一个实时的 HTMLCollection,其中包含当前元素的特定标签名的所有后代元素。
  • Element.getElementsByTagNameNS()(namespaceURI, localName),返回一个实时的 HTMLCollection,其中包含当前元素的特定标签名和命名空间的所有后代元素。
  • 属性操作:
  • Element.getAttribute()(attributeName),从当前节点读取指定属性的值,并以字符串形式返回。
  • Element.setAttribute()(name, value),设置当前节点的指定属性值。
  • Element.hasAttribute()(attributeName),返回一个布尔值,表示元素是否具有指定属性。
  • Element.removeAttribute()(attrName),从当前节点删除指定属性。
  • 属性操作-其他:
  • Element.hasAttributes()(),返回一个布尔值,表示元素是否具有一个或多个 HTML 属性。
  • Element.toggleAttribute()(name, force?),在指定的元素上切换布尔属性,如果存在则删除它,如果不存在则添加它。
  • 属性操作-NS:
  • Element.getAttributeNS()(namespace, name),从当前节点读取指定名称空间和名称的属性值,并以字符串形式返回。
  • Element.hasAttributeNS()(namespace,localName),返回一个布尔值,表示元素是否在指定名称空间中具有指定属性。
  • Element.requestFullscreen()(options?),异步要求浏览器全屏显示元素。
  • Element.scroll()(x, y) | (options),滚动到指定元素内部的特定坐标。
  • Element.scrollBy()(x, y) | (options),以给定数值滚动元素。
  • Element.scrollTo()(x, y) | (options),滚动到指定元素内部的特定坐标。
  • Element.scrollIntoView()(alignToTop?, scrollIntoViewOptions?),滚动页面,直到元素进入视图。

事件类型:

HTMLElement

继承:Element - Document - Node - EventTarget

实例属性:

Event

构造函数

  • Event()(type, options?),创建并返回一个 Event 对象。

实例属性

实例方法

UIEvent

构造函数

  • UIEvent()(type, options?),创建一个 UIEvent 对象。

实例属性

MouseEvent

继承 UIEvent、Event

构造函数

  • MouseEvent()(type, options?),生成一个新的 MouseEvent 对象

实例属性

MouseEvent-DragEvent

继承 MouseEvent、Event

构造函数

  • DragEvent()(type, dragEventInit?),创建合成和不可信的 DragEvent.

实例属性

事件类型

  • drag(event) => {},拖动元素或选择文本时触发此事件。
  • dragend(event) => {},当拖动操作结束时(释放鼠标按钮或按下退出键),会触发此事件。
  • dragenter(event) => {},当拖动的元素或选择文本输入有效的放置目标时,会触发此事件。
  • dragleave(event) => {},当拖动的元素或文本选择离开有效的放置目标时,会触发此事件。
  • dragover(event) => {},当将元素或文本选择拖动到有效放置目标(每几百毫秒)上时,会触发此事件。
  • dragstart(event) => {},当用户开始拖动元素或选择文本时触发此事件。
  • drop(event) => {},当在有效放置目标上放置元素或选择文本时触发此事件。
MouseEvent-WheelEvent

继承:MouseEvent - UIEvent - Event

构造函数

  • WheelEvent()(type, options?),创建一个 WheelEvent 对象。

实例属性

KeyboardEvent

继承:UIEvent - Event

构造函数

  • KeyboardEvent()(type, options?),创建一个新的 KeyboardEvent 对象。

实例属性

事件类型

  • keydown(event) => {},一个键被按下。
  • keyup(event) => {},一个键被释放。
ClipboardEvent

继承:Event

构造函数

  • ClipboardEvent()(type, options?),用给定的参数创建了一个 ClipboardEvent 事件。

实例属性

  • ClipboardEvent.clipboardDataDataTransfer,只读,包含了由用户发起的 cut 、 copy 和 paste 操作影响的数据,以及它的 MIME 类型。

事件类型

  • copy(event) => {},复制事件。
  • cut(event) => {},剪切事件。
  • paste(event) => {},粘贴事件。
InputEvent

继承:UIEvent - Event

构造函数

  • InputEvent()(type, options?),创建一个 InputEvent 对象。

实例属性

  • InputEvent.datastring,只读,返回包含插入字符的字符串,如果更改没有插入文本(例如删除字符时)则该值为空字符串。
  • InputEvent.dataTransferDataTransfer,只读,返回一个 DataTransfer 对象,该对象包含有关要添加到可编辑内容,或从可编辑内容中删除的富文本或纯文本数据的信息。
  • InputEvent.inputTypeinsertText | deleteContentBackward | insertFromPaste | formatBold,只读,返回对可编辑内容所做更改的类型,例如插入、删除或格式化文本。
  • 其他:InputEvent.isComposing

实例方法

  • InputEvent.getTargetRanges()(),返回一个 StaticRange 对象数组,如果不取消输入事件,该数组将受到 DOM 更改的影响。
TouchEvent

继承:UIEvent - Event

构造函数:

  • TouchEvent()(type, options?),创建一个TouchEvent对象。

实例属性:

  • TouchEvent.touchesTouchList,只读,一 个 TouchList 对象,包含了所有当前接触触摸平面的触点的 Touch 对象,无论它们的起始于哪个 element 上,也无论它们状态是否发生了变化。
  • TouchEvent.targetTouchesTouchList,只读,一个 TouchList 对象,是包含了如下触点的 Touch 对象:触摸起始于当前事件的目标 element 上,并且仍然没有离开触摸平面的触点。
  • TouchEvent.changedTouchesTouchList,只读,一个 TouchList 对象,包含了代表所有从上一次触摸事件到此次事件过程中,状态发生了改变的触点的 Touch 对象。
  • **其他:**TouchEvent.altKey,TouchEvent.ctrlKey,TouchEvent.metaKey,TouchEvent.shiftKey

事件类型:

  • touchstart(event) => {},当用户在触摸平面上放置了一个触点时触发。
  • touchend(event) => {},当一个触点被用户从触摸平面上移除(即用户的一个手指或手写笔离开触摸平面)时触发。当触点移出触摸平面的边界时也将触发。
  • touchmove(event) => {},当用户在触摸平面上移动触点时触发。
  • touchcancel(event) => {},当触点由于某些原因被中断时触发。如被弹窗打断,离开了文档窗口,触点个数超标。

其他

HTMLCollection

实例属性:

实例方法:

  • HTMLCollection.item()(index),根据给定的索引(从 0 开始),返回具体的节点。超出则返回 null。
  • HTMLCollection.namedItem()(key),根据 ID 返回指定节点,若不存在,则根据字符串所表示的 name 属性来匹配。

NodeList

实例属性:

实例方法:

  • NodeList.item()(index),返回 NodeList 对象中指定索引的节点,索引越界则返回null。
  • NodeList.entries()(),返回一个迭代协议,允许遍历此对象中包含的所有键/值。
  • NodeList.keys()(),遍历这个对象中包含的所有的键。
  • NodeList.values()(),遍历该对象中包含的所有值(Node 对象)的迭代器。
  • NodeList.forEach()(callback, thisArg?),按插入顺序为列表中的每个值对调用一次参数中给定的回调。即遍历 NodeList。

DataTransfer

构造函数:

  • DataTransfer()(),生成并且返回一个新的 DataTransfer 对象。

实例属性:

  • DataTransfer.dropEffectnone | copy | link | move,获取当前选定的拖放操作类型或者设置的为一个新的类型。
  • DataTransfer.effectAllowednone | copy | copyLink | copyMove | link | linkMove | move | all | uninitialized,提供所有可用的操作类型。
  • DataTransfer.filesFile[],包含数据传输中可用的所有本地文件的列表。如果拖动操作不涉及拖动文件,则此属性为空列表。
  • DataTransfer.itemsDataTransferItemList,只读,提供一个包含所有拖动数据列表的 DataTransferItemList 对象。
  • DataTransfer.typesstring[],只读,一个提供 dragstart 事件中设置的格式的 strings 数组。

实例方法:

  • DataTransfer.getData()(format),检索给定类型的数据,如果该类型的数据不存在或 data transfer 不包含数据,则返回空字符串。
  • DataTransfer.setData()(format, data),设置给定类型的数据。如果该类型的数据不存在,则将其添加到末尾,以便类型列表中的最后一项将是新的格式。如果该类型的数据已经存在,则在相同位置替换现有数据。
  • DataTransfer.clearData()(format?),删除与给定类型关联的数据。
  • DataTransfer.setDragImage()(imgElement, xOffset, yOffset),用于设置自定义的拖动图像。

概述

API

API(Application Programming Interface,应用程序编程接口):是一组预定义的函数、协议和工具,用于构建/集成应用程序,隐藏内部实现细节,仅暴露必要交互接口。

  • 任何开发语言都有自己的API
  • API的特征输入和输出(I/O)
    • var max = Math.max(1, 2, 3);
  • API的使用方法(console.log('adf'))

Web API

Web API:是浏览器提供的一组预定义接口,允许 JS 代码与浏览器功能、硬件设备或系统服务交互,从而赋予网页动态操作能力和高级功能。它是 Web 开发的核心基础,使开发者能够突破静态页面的限制,实现复杂的交互和数据通信。

常见API分类

  1. 文档对象模型:操作 HTML/CSS 结构

    • DOM API
  2. 网络通信:与服务器交换数据

    • Fetch API
    • XMLHttpRequest
  3. 客户端存储:在浏览器中持久化数据

    • Web Storage
    • IndexedDB
  4. 多媒体:图形绘制、音频处理

    • Canvas
    • Web Audio API
  5. 设备交互:访问硬件传感器

    • Geolocation
    • Device Orientation
  6. 异步任务管理:处理耗时操作

    • Promise
    • Web Workers

JS的组成

JS组成:JavaScript由以下三个部分组成:

  • ECMAScript:JavaScript 的语法和基础功能标准,由 ECMA International 组织维护(最新版本为 ES2025)。
  • DOM:将 HTML/XML 文档结构化为树状对象模型,提供操作页面内容的 API。
  • BOM:浏览器提供的与窗口、导航、屏幕等交互的非标准化 API。

image-20250426131857678

DOM

概念

DOM(Document Object Model,文档对象模型,文档树模型):是浏览器将 HTML/XML 文档解析为的结构化对象模型,它允许JS程序动态访问和操作页面内容、结构与样式。

DOM本质

  • 内存表示:HTML 文档被浏览器解析为树状数据结构,每个标签、属性、文本都成为树中的节点(Node)
  • 编程接口:提供 JavaScript 可调用的 API,实现页面交互(如点击事件、内容更新)。
  • 动态关联:DOM 与渲染引擎实时同步,修改 DOM 会触发浏览器重绘/重排。

DOM Tree

DOM Tree:一个页面不只是有html、head、body元素,也包括很多子元素,这些元素最终会在HTML结构中形成一个树结构。在抽象成DOM对象的时候,它们也会形成一个树结构,该结构就叫DOM Tree。

image-20250425223349748

DOM关系图

DOM相当于是JS和HTML、CSS之间的桥梁,通过浏览器提供给我们的DOM API,我们可以对元素以及其中的内容做任何事。

BOM

BOM(Browser Object Model,浏览器对象模型):是浏览器提供的与当前窗口或标签页交互的对象集合,允许开发者控制浏览器行为(如导航、窗口尺寸、历史记录等)。它与 DOM(文档对象模型)相辅相成,共同构成 Web 前端开发的核心能力。

对比DOM

维度BOMDOM
作用对象浏览器窗口、导航、历史等网页文档内容(HTML/XML)
标准化无统一标准(但现代浏览器行为趋同)W3C 标准规范
核心对象windowlocationhistorydocument、元素节点
应用场景控制浏览器行为操作页面内容

核心对象

  1. window:顶级对象,所有全局变量和函数都是 window 的属性。
  2. navigator:浏览器信息。
  3. location:URL 管理。
  4. history:浏览历史。
  5. screen:屏幕信息。

document

documentDocument,是浏览器环境中全局对象 window 的属性,代表当前加载的网页文档,是 DOM 的入口点。它提供了访问和操作页面内容的核心 API,是前端开发最基础且重要的对象。

核心作用

  1. DOM访问入口:整个 HTML 文档的根节点。
  2. 页面元数据管理:标题、URL、Cookie 等。
  3. 动态内容操作:增删改查元素、样式、事件。
  4. 资源加载控制:脚本、样式表、图片的加载。

常用属性

  • document.documentElementElement只读,返回当前文档的直接子节点。对于 HTML 文档一般代表该文档的 html 元素。
  • document.bodybody|frameset|null,获取或设置当前文档的 bodyframeset节点(不常用设置)。
  • document.headHTMLHeadElement只读,返回当前文档的 head 元素。
  • document.titlestring,获取或设置当前文档的标题
  • document.doctypeDocumentType只读,返回当前文档的文档类型定义DTD<!DOCTYPE html>)。
  • document.imagesHTMLCollection只读,返回当前文档中所包含的图片的 HTMLCollection。
  • document.scriptsHTMLCollection只读,返回包含文档中所有的 script 元素的 HTMLCollection。
  • document.linksHTMLCollection只读,返回一个包含文档中所有超链接的 HTMLCollection。
  • document.formsHTMLCollection只读,返回一个包含当前文档中所有表单元素 form 的 HTMLCollection。
  • document.cookiestring,返回一个使用分号分隔的 cookie 列表,或设置(写入)一个 cookie。

常用方法

DOM操作

导航

节点导航

节点导航:如果我们获取到一个节点(Node)后,可以根据这个节点去获取其他的节点,我们称之为节点之间的导航。

常见节点导航 API

适用于处理 所有类型节点(元素、文本、注释等),返回的节点可能包含非元素类型。

  • node.parentNodeNode|null只读,返回一个当前节点的父节点
  • node.previousSiblingNode|null只读,返回与该节点同级的前一个节点
  • node.nextSiblingNode|null只读,返回与该节点同级的下一个节点
  • node.childNodesNodeList只读,返回一个包含了该节点所有子节点动态变化的的NodeList。
  • node.firstChildNode|null只读,返回该节点的第一个子节点
  • node.lastChildNode|null只读,返回该节点的最后一个子节点

image-20250426104821016

元素导航@

常见元素导航 API

专用于 元素节点(Element),自动过滤非元素节点,更符合日常开发需求。

image-20250426112234230

table导航

table:在 DOM 中拥有独特的导航方法,通过特定属性和集合可快速定位行列数据。

常见table导航 API

  • table
  • table.captionHTMLTableCaptionElement|null,获取/设置表格标题元素(如果存在)。
  • table.tHeadHTMLTableSectionElement|null,获取/设置表格的 thead 元素(如果存在)。
  • table.tFootHTMLTableSectionElement|null,获取/设置表格的 tfoot 元素(如果存在)。
  • table.tBodiesHTMLCollection只读,返回包含元素中的所有 tbody动态集合
  • table.rowsHTMLCollection只读,返回包含元素中的所有 tr动态集合
  • row
  • row.cellsHTMLCollection只读,获取行内所有单元格(td,th)动态集合
  • row.sectionRowIndexnumber只读,获取行在表格body区域中的索引
  • row.rowIndexnumber只读,获取行在整个表格中的索引
  • cell
  • cell.cellIndexnumber只读,获取单元格在行中的索引
  • cell.colSpannumber,获取/设置跨列数
  • cell.rowSpannumber,获取/设置跨行数

image-20250426120312009

练习:实现如下效果【

image-20250426141420809

form导航

form:是用户输入的核心组件,DOM 提供了丰富的 API 用于访问和操作表单及其控件。

常见form导航 API

  • document
  • document.formsHTMLCollection只读,返回一个包含当前文档中所有表单元素 form 的 HTMLCollection。
  • form
  • form.elementsHTMLFormControlsCollection只读,返回 form 元素中包含的所有表单控件

访问表单元素控件的方法

  1. 通过索引访问

    js
    const firstElement = form.elements[0]; // 第一个表单控件
  2. 通过 name 或 id 访问

    html
    <form id="myForm">
      <input type="text" name="username" id="user">
      <input type="radio" name="gender" value="male">
      <input type="radio" name="gender" value="female">
    </form>
    js
    const form = document.getElementById('myForm');
    
    // 访问单个元素
    const usernameInput = form.elements.username; // 或 form.elements['username']
    
    // 访问同名元素(如单选按钮)
    const genderRadios = form.elements.gender; // 返回 RadioNodeList
    console.log(genderRadios.value); // 输出选中的值(如 "male")
  3. 使用 namedItem() 方法

    js
    const userElement = form.elements.namedItem('user'); // 通过 id="user" 查找

获取元素

我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,才能进行后续操作。

传统方法

传统方法

示例

js
const header = document.getElementById('main-header');

const buttons = document.getElementsByClassName('btn primary');

const images = document.getElementsByTagName('img');
getElementById()

document.getElementById()(id),返回与ID匹配的元素

核心特性

  • ID 唯一:HTML 文档中 ID 应唯一,多个相同 ID 时返回第一个匹配元素(行为不确定,需避免此情况)。
  • 区分大小写:ID会区分大小写,Headerheader是不同的ID。
  • DOM 加载时机:需确保元素已加载到 DOM 中,否则返回 null(建议在 DOMContentLoaded 事件后调用)。
  • 性能优化:浏览器内部通过哈希表加速查找,时间复杂度为 O(1)。
  • 动态元素支持:动态添加的元素(如通过 JS 插入)只要 ID 唯一且已插入 DOM,即可被找到。

示例

  1. 基本用法

    html
    <div id="content">页面内容</div>
    js
    // 获取元素并修改内容
    const contentDiv = document.getElementById('content');
    if (contentDiv) {
      contentDiv.textContent = '更新后的内容';
    }
  2. 动态元素处理

    js
    // 动态创建元素并插入 DOM
    const newElement = document.createElement('div');
    newElement.id = 'dynamicElement';
    document.body.appendChild(newElement);
    
    // 立即获取(有效)
    const dynamicElement = document.getElementById('dynamicElement');
    console.log(dynamicElement); // 输出: <div id="dynamicElement"></div>
getElementsByClassName()

document.getElementsByClassName()(names),返回匹配给定类名的元素列表。

el.getElementsByClassName()(names),返回匹配给定类名的元素列表。

核心特性

  • 类名顺序无关:参数中的类名顺序不影响匹配(如 "active btn""btn active" 等效)
  • 部分匹配无效:必须完全包含所有指定的类名(如 class="btn-primary" 不会被 "btn" 匹配)
  • 多类名逻辑:多个类名用空格分隔,方法会匹配所有同时包含这些类名的元素。
  • 作用域限制:可通过父元素调用以限定搜索范围
  • 动态性:返回的HTMLCollection集合会随 DOM 变化自动更新(如新增/删除符合条件的元素)。
  • 兼容性:支持所有现代浏览器(IE9+),但 IE8 及更早版本不支持

示例

  1. 基本用法

    html
    <div class="item">Item 1</div>
    <div class="item active">Item 2</div>
    <div class="item">Item 3</div>
    js
    // 获取所有包含 "item" 类的元素
    const items = document.getElementsByClassName("item");
    console.log(items.length); // 输出: 3
    
    // 获取同时包含 "item" 和 "active" 类的元素
    const activeItem = document.getElementsByClassName("item active");
    console.log(activeItem.length); // 输出: 1
  2. 限定作用域

    html
    <div id="container">
      <div class="box">Box 1</div>
      <div class="box">Box 2</div>
    </div>
    js
    const container = document.getElementById("container");
    const boxes = container.getElementsByClassName("box"); // 仅在容器内查找
  3. 处理动态集合

    js
    const buttons = document.getElementsByClassName("btn");
    
    // 新增一个按钮(自动加入集合)
    const newButton = document.createElement("button");
    newButton.className = "btn";
    document.body.appendChild(newButton);
    console.log(buttons.length); // 输出: 原数量 + 1
    
    // 删除一个按钮(自动从集合移除)
    document.querySelector(".btn").remove();
    console.log(buttons.length); // 输出: 原数量 - 1
getElementsByTagName()

document.getElementsByTagName()(tagname|*),返回匹配给定标签名的元素列表。

el.getElementsByTagName()(tagname|*),返回匹配给定标签名的元素列表。

核心特性

  • 大小写区分
    • HTML 文档中标签名大小写不敏感(如 "DIV""div" 等效)。
    • XML/XHTML 文档中,标签名可能区分大小写。
  • 仅匹配元素节点:忽略文本节点、注释节点等非元素节点
  • 全局与局部作用域:可在 document特定父元素上调用以限定搜索范围
  • 通配符支持"*" 匹配所有元素(谨慎使用,可能影响性能)
  • 动态性:返回的HTMLCollection集合会随 DOM 变化自动更新(如新增/删除符合条件的元素)。
  • 兼容性:所有现代浏览器(包括 IE6+)
  • 性能优化:标签名查询速度较快,但大规模文档中建议限定作用域

示例

  1. 基础用法

    html
    <div>Div 1</div>
    <div>Div 2</div>
    <p>段落</p>
    js
    // 获取所有 div 元素
    const divs = document.getElementsByTagName("div");
    console.log(divs.length); // 输出: 2
    
    // 获取所有段落元素
    const paragraphs = document.getElementsByTagName("p");
    console.log(paragraphs[0].textContent); // 输出: "段落"
  2. 使用通配符 *

    js
    // 获取文档中所有元素
    const allElements = document.getElementsByTagName("*");
    console.log(allElements.length); // 输出文档总元素数
  3. 限定作用域

    html
    <ul id="list">
      <li>Item 1</li>
      <li>Item 2</li>
    </ul>
    js
    const list = document.getElementById("list");
    const items = list.getElementsByTagName("li"); // 仅在列表内查找
    console.log(items.length); // 输出: 2
  4. 处理动态集合

    js
    const divs = document.getElementsByTagName("div");
    
    // 动态添加元素(自动加入集合)
    const newDiv = document.createElement("div");
    document.body.appendChild(newDiv);
    console.log(divs.length); // 输出: 原数量 + 1
    
    // 动态删除元素(自动从集合移除)
    document.querySelector("div").remove();
    console.log(divs.length); // 输出: 原数量 - 1

现代方法

现代方法

querySelector()

document.querySelector()(selectors),返回文档中与指定的选择器匹配的第一个元素节点

el.querySelector()(selectors),返回文档中与指定的选择器匹配的第一个元素节点

核心特性

  • 选择器规则:选择器遵循CSS的选择器规则
  • 仅返回首个匹配项:即使有多个匹配元素,也只返回第一个
  • 作用域限定:在父元素上调用时,仅搜索其后代元素
  • 静态结果:返回的是查询时的快照,DOM 后续变化不影响结果(需重新查询)
  • 性能优化:复杂选择器可能影响性能(推荐优先使用 ID 或类名选择器)
  • 兼容性:支持所有现代浏览器(IE8+ 部分支持,需 CSS2 选择器)

示例

  1. 基础用法

    js
    // 按 ID 选择(等效于 getElementById,但更灵活)
    const header = document.querySelector('#header');
    
    // 按类名选择(返回第一个匹配项)
    const firstActiveItem = document.querySelector('.item.active');
    
    // 按标签名选择(返回第一个 div)
    const firstDiv = document.querySelector('div');
  2. 复合选择器

    js
    // 选择类为 btn 的 button 元素
    const button = document.querySelector('button.btn');
    
    // 选择 type 为 email 的输入框
    const emailInput = document.querySelector('input[type="email"]');
    
    // 选择直接子元素(ul 下的第一层 li)
    const listItem = document.querySelector('ul > li');
  3. 伪类选择器

    js
    // 选择第一个段落(CSS 伪类)
    const firstParagraph = document.querySelector('p:first-of-type');
    
    // 选择被勾选的复选框
    const checkedBox = document.querySelector('input[type="checkbox"]:checked');
querySelectorAll()

document.querySelectorAll()(selectors),返回包含文档中与指定的选择器匹配的所有元素节点的列表。

el.querySelectorAll()(selectors),返回包含文档中与指定的选择器匹配的所有元素节点的列表。

核心特性

  • 选择器规则:选择器遵循CSS的选择器规则
  • 返回所有匹配项特殊,返回全部匹配元素(非仅第一个)
  • 作用域限定:在父元素上调用时,仅搜索其后代元素
  • 静态结果:返回的是查询时的快照,DOM 后续变化不影响结果(需重新查询)
  • 遍历方式特殊,支持 forEach() 方法,或转换为数组操作
  • 性能优化:复杂选择器可能影响性能(推荐优先使用 ID 或类名选择器)
  • 兼容性:支持所有现代浏览器(IE8+ 部分支持,需 CSS2 选择器)

示例

  1. 基础用法

    js
    // 选择所有类名为 "item" 的元素
    const items = document.querySelectorAll('.item');
    items.forEach(item => {
      console.log(item.textContent);
    });
    
    // 选择所有段落中的链接
    const linksInParagraphs = document.querySelectorAll('p a');
  2. 转换为数组操作

    js
    const buttons = document.querySelectorAll('.btn');
    const buttonsArray = Array.from(buttons); // 或 [...buttons]
    
    // 使用数组方法过滤元素
    const activeButtons = buttonsArray.filter(btn => btn.disabled === false);

节点属性

节点常见属性

  • node.nodeTypenumber只读,用于标识节点的类型
  • node.nodeNameDOMString只读,返回当前节点的节点名称。
  • el.tagNamestring只读,返回当前元素的标签名。
  • el.innerHTMLDOMString,获取/设置 HTML 语法表示的元素的后代
  • node.textContentstring|null,返回/设置一个元素内所有子节点及其后代的文本内容
  • node.outerHTMLDOMString,获取/设置 HTML 语法表示的元素以及其后代
  • node.data/nodeValue:``,获取非元素节点的文本内容。

nodeType

node.nodeTypenumber只读,用于标识节点的类型

DOM常见节点类型

类型(Node Type)常量常量值示例
元素节点Node.ELEMENT_NODE1<div>, <p>, <a>
属性节点(已废弃)Node.ATTRIBUTE_NODE2class="content"
文本节点Node.TEXT_NODE3'段落'
注释节点Node.COMMENT_NODE8<!-- 注释 -->
文档节点Node.DOCUMENT_NODE9document 对象
文档类型节点Node.DOCUMENT_TYPE_NODE10<!DOCTYPE html>

示例

  1. 判断元素节点

    js
    const element = document.getElementById("header");
    if (element.nodeType === Node.ELEMENT_NODE) { // 或 element.nodeType === 1
      console.log("这是一个元素节点");
    }
  2. 过滤文本节点

    html
    <div id="content">Hello <!-- 注释 --> World</div>
    js
    const div = document.getElementById("content");
    div.childNodes.forEach(node => {
      if (node.nodeType === Node.TEXT_NODE) {
        console.log("文本内容:", node.textContent); // 输出 "Hello " 和 " World"
      }
    });

元素操作

创建元素【

write()

image-20250428145843612

javascript
document.write('新设置的内容<p>标签也可以生成</p>');
innerHTML
javascript
var box = document.getElementById('box');
box.innerHTML = '新内容<p>新标签</p>';
createElement()
javascript
var div = document.createElement('div');
document.body.appendChild(div);
性能问题
  • innerHTML方法由于会对字符串进行解析,需要避免在循环内多次使用。
  • 可以借助字符串或数组的方式进行替换,再设置给innerHTML
  • 优化后与document.createElement性能相近
案例
  • 动态创建列表,高亮显示
  • 根据数据动态创建表格

插入元素【

  • node.append()()
  • node.prepend()()
  • node.before()()
  • node.after()()
  • node.replaceWith()()

image-20250428151102647

image-20250428151118908

移除元素【

image-20250428152936955

  • el.remove()()

image-20250428152114731

克隆元素【

image-20250428152948413

  • node.cloneNode()()

image-20250428152619226

旧元素操作方法【

image-20250428153035112

案例

案例一动态创建列表

image-20250428170829648

案例二时间显示

image-20250428172149727

image-20250428172210969

image-20250428172411496

案例三倒计时

image-20250428175252562

image-20250428175218927

尺寸位置滚动

元素尺寸位置滚动【

image-20250428163127299

image-20250428155348036

window尺寸滚动【

image-20250428164448756

image-20250428165519073

属性

元素属性 Attribute

元素属性(Attribute):是添加到 HTML 标签中的额外信息,用于定义元素的行为、样式、数据或其他特性。属性以键值对的形式存在(如 name="value"),为元素提供丰富的功能扩展。

语法格式

html
<标签名 属性1="值1" 属性2="值2">内容</标签名>
<!-- 示例 -->
<a href="https://example.com" target="_blank">访问示例</a>

特性

  • 大小写不敏感
  • 属性值为字符串类型

元素属性的分类

  • 标准Attribute

    • 全局属性
    • 功能属性
    • 事件处理器属性
  • 非标准Attribute

全局属性

全局属性:是所有 HTML 元素共有的属性;它们可以用于所有元素,即使属性可能对某些元素不起作用。

常见全局属性

  • id唯一标识符,用于CSS或JavaScript精准选择元素。
  • class:为元素指定一个或多个类名(用空格分隔),用于CSS样式或JavaScript选择。
  • titleJS:el.title,提供额外信息,通常显示为工具提示
  • styleJS:el.style,内联CSS样式(优先级高)。
  • data-*JS:el.dataset,存储自定义数据(*为自定义名称),通过JavaScript的dataset访问。
  • hiddenJS:el.hidden,隐藏元素(等效于display: none)。
  • draggableJS:el.draggable,控制元素是否可拖动(需配合拖放API)。
表单元素属性【
  • value 用于大部分表单元素的内容获取(option除外)
  • type 可以获取input标签的类型(输入框或复选框等)
  • disabled 禁用属性
  • checked 复选框选中属性
  • selected 下拉菜单选中属性

元素对象属性 Property

通用属性操作

通用属性方法

通用属性方法支持所有的attribute的访问,包括标准和非标准的属性:

  • el.attributesNamedNodeMap只读,返回一个 NamedNodeMap 对象,其中包含相应 HTML 元素的指定属性。
  • el.getAttribute()(attributeName),从当前节点获取指定属性的值,并以字符串形式返回。
  • el.setAttribute()(name, value)设置当前节点的指定属性值,若属性不存在则创建。
  • el.hasAttribute()(attributeName),返回一个布尔值,表示元素是否具有指定属性
  • el.removeAttribute()(attrName),从当前节点删除指定属性。

示例

  1. 获取所有属性

    html
    <a id="link" href="https://example.com" target="_blank">链接</a>
    js
    const link = document.getElementById('link');
    const attrs = link.attributes;
    
    // 输出所有属性及值
    Array.from(attrs).forEach(attr => {
      console.log(`${attr.name}: ${attr.value}`);
    });
    // 输出:
    // id: link
    // href: https://example.com
    // target: _blank
  2. 访问指定属性

    js
    const link = document.querySelector('a');
    const href = link.getAttribute('href'); // 返回链接地址(字符串)
  3. 设置指定属性

    js
    const img = document.querySelector('img');
    img.setAttribute('alt', '产品图片'); // 设置 alt 属性
  4. 检查属性存在

    js
    const checkbox = document.querySelector('input[type="checkbox"]');
    if (checkbox.hasAttribute('checked')) {
      console.log('复选框默认选中');
    }
  5. 移除指定属性

    js
    const input = document.querySelector('input');
    input.removeAttribute('disabled'); // 移除禁用状态

标准属性操作

对于标准attribute,会在DOM对象上创建与其对应的property属性:

image-20250428112734700

Property对比Attribute

  • 大多数情况下,它们是相互作用的:
    • 改变property,通过attribute获取的值会随之变化
    • 改变attribute,property对应的值也会随之变化
  • 除非特殊情况,设置/获取属性推荐使用property的方式,因为它默认是有类型提示的。

image-20250426181226560

类名 className/classList

操作class的方法:

方法一:通过 className 操作

缺点:会覆盖之前的class

示例

js
var box = document.getElementById('box');
box.className = 'show';

方法二:通过 classList 操作(推荐)

如果需要添加或移除单个class,可以使用classList属性。

示例

  1. 基本使用

    html
    <div class="foo"></div>
    js
    const div = document.createElement("div");
    
    // 1. 移除
    div.classList.remove("foo"); // <div class=""></div>
    
    // 2. 添加
    div.classList.add("anotherclass"); // <div class="anotherclass"></div>
    
    // 3. 切换
    div.classList.toggle("visible"); // <div class="anotherclass visible"></div>
    
    // 4. 是否存在
    console.log(div.classList.contains("foo")); // false
  2. 高级使用

    js
    // 1. 添加或移除多个类值
    div.classList.add("foo", "bar", "baz");
    div.classList.remove("foo", "bar", "baz");
    
    // 2. 使用展开语法添加或移除多个类值
    const cls = ["foo", "bar"];
    div.classList.add(...cls);
    div.classList.remove(...cls);
    
    // 3. 将类值 "foo" 替换成 "bar"
    div.classList.replace("foo", "bar");
样式 style【

使用style方式设置的样式显示在标签行内

javascript
var box = document.getElementById('box');
box.style.width = '100px';
box.style.height = '100px';
box.style.backgroundColor = 'red';

注意

通过样式属性设置宽高、位置的属性类型是字符串,需要加上px

设置样式

image-20250428144059243

image-20250428144101411

读取样式

image-20250428144527140

image-20250428144503886

设置多个样式@

方式一:style.cssText,可以通过修改 style.cssText 属性来一次性设置多个 CSS 样式

js
// 获取元素
const element = document.getElementById("myElement");

// 一次性修改多个样式
element.style.cssText = "background-color: red; font-size: 20px; color: white;";

方式二:setAttribute(),可以通过 setAttribute 方法设置 style 一次性修改多个样式

js
// 获取元素
const element = document.getElementById("myElement");

// 一次性修改多个样式
element.setAttribute("style", "background-color: red; font-size: 20px; color: white;");

方式三:Object.assign(),可以通过JS的 Object.assign() 方法将多个样式合并到元素的 style 属性中。

js
// 获取元素
const element = document.getElementById("myElement");

// 使用 Object.assign 一次性设置多个样式
Object.assign(element.style, {
  backgroundColor: 'red',
  fontSize: '20px',
  color: 'white'
});
自定义属性 dataset

image-20250428145144419

image-20250428144912810

事件

概念

认识事件

事件处理方式

事件冒泡/捕获

事件对象 event

EventTarget

事件委托模式

常见事件

案例

事件:触发-响应机制

事件三要素

  • 事件源:触发(被)事件的元素
  • 事件名称: click 点击事件
  • 事件处理程序:事件触发后要执行的代码(函数形式)

事件的基本使用

javascript
var box = document.getElementById('box');
box.onclick = function() {
  console.log('代码会在box被点击后执行');  
};

节点操作

javascript
var body = document.body;
var div = document.createElement('div');
body.appendChild(div);

var firstEle = body.children[0];
body.insertBefore(div, firstEle);

body.removeChild(firstEle);

var text = document.createElement('p');
body.replaceChild(text, div);

案例:

​ 选择水果

事件详解

注册/移除事件的三种方式

javascript
var box = document.getElementById('box');
box.onclick = function () {
  console.log('点击后执行');
};
box.onclick = null;

box.addEventListener('click', eventCode, false);
box.removeEventListener('click', eventCode, false);

box.attachEvent('onclick', eventCode);
box.detachEvent('onclick', eventCode);

function eventCode() {
  console.log('点击后执行');
}

兼容代码

javascript
function addEventListener(element, type, fn) {
  if (element.addEventListener) {
    element.addEventListener(type, fn, false);
  } else if (element.attachEvent){
    element.attachEvent('on' + type,fn);
  } else {
    element['on' + type] = fn;
  }
}

function removeEventListener(element, type, fn) {
  if (element.removeEventListener) {
    element.removeEventListener(type, fn, false);
  } else if (element.detachEvent) {
    element.detachEvent('on' + type, fn);
  } else {
    element['on'+type] = null;
  }
}

事件的三个阶段

  1. 捕获阶段

  2. 当前目标阶段

  3. 冒泡阶段

    事件对象.eventPhase属性可以查看事件触发时所处的阶段

事件对象的属性和方法

  • event.type 获取事件类型
  • clientX/clientY 所有浏览器都支持,窗口位置
  • pageX/pageY IE8以前不支持,页面位置
  • event.target || event.srcElement 用于获取触发事件的元素
  • event.preventDefault() 取消默认行为

案例

  • 跟着鼠标飞的天使
  • 鼠标点哪图片飞到哪里
  • 获取鼠标在div内的坐标

阻止事件传播的方式

  • 标准方式 event.stopPropagation();
  • IE低版本 event.cancelBubble = true; 标准中已废弃

常用的鼠标和键盘事件

  • onmouseup 鼠标按键放开时触发
  • onmousedown 鼠标按键按下触发
  • onmousemove 鼠标移动触发
  • onkeyup 键盘按键按下触发
  • onkeydown 键盘按键抬起触发

特效

偏移量

  • offsetParent用于获取距离当前元素最近定位父级元素
  • offsetParent和parentNode的区别
javascript
var box = document.getElementById('box');

console.log(box.offsetParent);
// 获取距离当前元素最近的定位父级元素
console.log(box.offsetLeft);
console.log(box.offsetTop);
// 大小包括border和padding
console.log(box.offsetWidth);
console.log(box.offsetHeight);

客户区大小

javascript
var box = document.getElementById('box');
// client** 是border的宽度
console.log(box.clientLeft);
console.log(box.clientTop);
// 获取大小 包括padding 但是不包括border
console.log(box.clientWidth);
console.log(box.clientHeight);

滚动偏移

javascript
var box = document.getElementById('box');
// box 滚动出去的距离
console.log(box.scrollLeft)
console.log(box.scrollTop)

console.log(box.scrollWidth)
console.log(box.scrollHeight)

案例

  • 拖拽案例
  • 弹出登录窗口
  • 放大镜案例
  • 模拟滚动条
  • 匀速动画函数
  • 变速动画函数
  • 无缝轮播图
  • 回到顶部

附录

元素的类型